package com.xnx.bincker.leader.core.security;

import com.xnx.bincker.leader.exception.data.RequestParameterErrorException;
import lombok.Data;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 自定义登录验证
 */
public class CustomUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    protected CustomUsernamePasswordAuthenticationFilter(RequestMatcher requiresAuthenticationRequestMatcher) {
        super(requiresAuthenticationRequestMatcher);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        UserAuthenticationBean userAuthentication = obtainUserAuthentication(request);
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userAuthentication.username, userAuthentication.password);
        this.setDetails(request, token);
        return getAuthenticationManager().authenticate(token);
    }

    private void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken token) {
        token.setDetails(authenticationDetailsSource.buildDetails(request));
    }

    protected UserAuthenticationBean obtainUserAuthentication(HttpServletRequest request){
        try {
            return Jackson2ObjectMapperBuilder.json().build().readValue(request.getInputStream(), UserAuthenticationBean.class);
        } catch (IOException e) {
            throw new RequestParameterErrorException();
        }
    }

    @Data
    public static class UserAuthenticationBean{
        String username;
        String password;

        public void setUsername(String username) {
            if(username == null) username = "";
            this.username = username.trim();
        }

        public void setPassword(String password) {
            if(password == null) password = "";
            this.password = password;
        }
    }
}
